package butterknife;

import ohos.agp.components.Component;
import ohos.utils.ObjectAttribute;

import java.util.List;

/** Convenience methods for working with view collections. */
public final class ViewCollections {
  /** Apply the specified {@code actions} across the {@code list} of components.
   * @param list List of components
   * @param actions array of actions
   * */
  @SafeVarargs public static <T extends Component> void run(List<T> list,
                                                            Action<? super T>... actions) {
    for (int i = 0, count = list.size(); i < count; i++) {
      for (Action<? super T> action : actions) {
        action.apply(list.get(i), i);
      }
    }
  }

  /** Apply the specified {@code actions} across the {@code array} of components.
   * @param list List of components
   * @param actions array of actions
   * */
  @SafeVarargs public static <T extends Component> void run(T[] array,
      Action<? super T>... actions) {
    for (int i = 0, count = array.length; i < count; i++) {
      for (Action<? super T> action : actions) {
        action.apply(array[i], i);
      }
    }
  }

  /** Apply the specified {@code action} across the {@code list} of components.
   * @param list List of components
   * @param action action
   * */
  public static <T extends Component> void run(List<T> list,
      Action<? super T> action) {
    for (int i = 0, count = list.size(); i < count; i++) {
      action.apply(list.get(i), i);
    }
  }

  /** Apply the specified {@code action} across the {@code array} of components.
   * @param array array of components
   * @param action action
   * */
  public static <T extends Component> void run(T[] array, Action<? super T> action) {
    for (int i = 0, count = array.length; i < count; i++) {
      action.apply(array[i], i);
    }
  }

  /** Apply {@code actions} to {@code view}.
   * @param view component to apply action
   * @param actions array of actions
   * */
  @SafeVarargs public static <T extends Component> void run(T view,
      Action<? super T>... actions) {
    for (Action<? super T> action : actions) {
      action.apply(view, 0);
    }
  }

  /** Apply {@code action} to {@code view}.
   * @param view component
   * @param action action
   * */
  public static <T extends Component> void run(T view, Action<? super T> action) {
    action.apply(view, 0);
  }

  /** Set the {@code value} using the specified {@code setter} across the {@code list} of components.
   * @param list list of components
   * @param setter setter
   * @param value value
   * */
  public static <T extends Component, V> void set(List<T> list,
      Setter<? super T, V> setter, V value) {
    for (int i = 0, count = list.size(); i < count; i++) {
      setter.set(list.get(i), value, i);
    }
  }

  /** Set the {@code value} using the specified {@code setter} across the {@code array} of components.
   * @param array array of components
   * @param setter setter
   * @param value value
   * */
  public static <T extends Component, V> void set(T[] array,
      Setter<? super T, V> setter, V value) {
    for (int i = 0, count = array.length; i < count; i++) {
      setter.set(array[i], value, i);
    }
  }

  /** Set {@code value} on {@code view} using {@code setter}.
   * @param view component
   * @param setter setter
   * @param value value
   * */
  public static <T extends Component, V> void set(T view,
      Setter<? super T, V> setter, V value) {
    setter.set(view, value, 0);
  }

  /**
   * Apply the specified {@code value} across the {@code list} of components using the {@code property}.
   * @param list array of components
   * @param setter setter
   * @param value value
   */
  public static <T extends Component, V> void set(List<T> list,
                                                  ObjectAttribute<? super T, V> setter, V value) {
    //noinspection ForLoopReplaceableByForEach
    for (int i = 0, count = list.size(); i < count; i++) {
      setter.set(list.get(i), value);
    }
  }

  /**
   * Apply the specified {@code value} across the {@code array} of components using the {@code property}.
   * @param list array of components
   * @param setter setter
   * @param value value
   */
  public static <T extends Component, V> void set(T[] array,
                                                  ObjectAttribute<? super T, V> setter, V value) {
    //noinspection ForLoopReplaceableByForEach
    for (int i = 0, count = array.length; i < count; i++) {
      setter.set(array[i], value);
    }
  }

  /** Apply {@code value} to {@code view} using {@code property}.
   * @param view component
   * @param setter setter
   * @param value value
   * */
  public static <T extends Component, V> void set(T view,
                                                  ObjectAttribute<? super T, V> setter, V value) {
    setter.set(view, value);
  }

  private ViewCollections() {
  }
}
